package com.shenyaocn.android.demovideo;

import android.graphics.SurfaceTexture;
import android.hardware.usb.UsbDevice;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TextView;

import com.shenyaocn.android.OpenH264.Decoder;
import com.shenyaocn.android.UartVideo.VideoClient;
import com.shenyaocn.android.UartVideo.usb.DeviceFilter;
import com.shenyaocn.android.UartVideo.usb.USBMonitor;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private VideoClient video;
    //
    // VideoClient function
    //
    // Send transmission data
    // sendData(data); unlimited length, SDK automatic subcontracting
    //
    // Send GPS data
    // sendGPS(data); unlimited length, SDK automatic subcontracting
    //
    // Send debug data
    // sendDebug(data); unlimited length, SDK automatic subcontracting
    //
    //
    // Set the exposure
    // VideoClient.setExposureTime(int time, boolean auto)
    // time: exposure time range 0 - 16384
    // auto: enable auto exposure, set true to ignore the time parameter
    //
    //
    // Set brightness/contrast/hue/saturation
    // VideoClient.setCSC(int brightness, int contrast, int hue, int saturation)
    // range 0 - 100
    //
    //
    // Toggle LED
    // VideoClient.toggleLED()
    //
    //
    //
    // Set resolution VideoClient.setVideoSize(VideoClient.Sizes size)
    // size resolution enumeration
    //        Size_Smooth
    //        Size_SD
    //        Size_HD
    //        Size_FHD
    //
    //
    // Open video device
    // boolean VideoClient.openUsbSerial(UsbDevice device)
    // device: Usb serial device that has obtained permission. Refer to the following sample code for more info
    // return value, success on true, failure on false
    //
    //
    // 关闭/停止回放 VideoClient.stopPlayback
    //
    // 参考下列代码获取H.264数据
    //
    // VideoClient 函数
    //
    // 发送数传数据 sendData(data); 长度不限，SDK自动分包
    //
    // 发送GPS数据 sendGPS(data); 长度不限，SDK自动分包
    //
    // 发送调试数据 sendDebug(data); 长度不限，SDK自动分包
    //
    //
    // 设置曝光 VideoClient.setExposureTime(int time, boolean auto)
    // time 曝光时间 范围 0 - 16384
    // auto 是否启用自动曝光，设true将忽略 time参数
    //
    //
    //
    // 设置亮度/对比度/色调/饱和度
    // VideoClient.setCSC(int brightness, int contrast, int hue, int saturation)
    // 范围都是 0 - 100
    //
    //
    //
    // 开关LED VideoClient.toggleLED()
    //
    //
    //
    // 设置分辨率 VideoClient.setVideoSize(VideoClient.Sizes size)
    // size 分辨率 枚举值
    //        Size_Smooth
    //        Size_SD
    //        Size_HD
    //        Size_FHD
    //
    //
    // 打开图传 boolean VideoClient.openUsbSerial(UsbDevice device)
    // device 已经获得权限的 Usb串口设备 参照以下示例代码操作
    // 返回值，成功 true 失败 false
    //
    //
    // 关闭/停止回放 VideoClient.stopPlayback
    //
    // 参考下列代码获取H.264数据

    private USBMonitor mUSBMonitor;
    private UsbDevice uartDevice;
    private Spinner spinner;
    private ScrollView scrollView;
    private TextView tv_content;
    private StringBuilder sb = new StringBuilder();
    private TextView tv_count;
    private RadioGroup radioGroup;
    private EditText et_send;
    private boolean hex = true;
    private int  passageway = 1;

    //使用 USBMonitor 处理USB连接回调
    private final USBMonitor.OnDeviceConnectListener mOnDeviceConnectListener = new USBMonitor.OnDeviceConnectListener() {
        // USB device attach
        // USB设备插入
        @Override
        public void onAttach(final UsbDevice device) {

            if(deviceHasConnected(device) || uartDevice != null)
                return;

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (device == null) {
                            final List<UsbDevice> devices = mUSBMonitor.getDeviceList();
                            if (devices.size() == 1) {
                                mUSBMonitor.requestPermission(devices.get(0));
                            }
                        } else {
                            mUSBMonitor.requestPermission(device);
                        }
                    } catch (Exception e){
                        e.printStackTrace();
                    }
                }
            });
        }

        // USB device detach
        // USB设备物理断开
        @Override
        public void onDettach(UsbDevice device) {
            if(!deviceIsUartVideoDevice(device)) {
                return;
            }

            if(!deviceHasConnected(device)) {
                return;
            }

            disconnected();
        }

        // USB device has obtained permission
        // USB设备获得权限
        @Override
        public void onConnect(UsbDevice device, USBMonitor.UsbControlBlock ctrlBlock, boolean createNew) {
            if(!deviceIsUartVideoDevice(device)) {
                return;
            }
            if(deviceHasConnected(device)) {
                return;
            }

            synchronized (this) {
                if(deviceIsUartVideoDevice(device)) {
                    if(video.openUsbSerial(device))
                        uartDevice = device;
                }
            }
        }
        // USB device disconnected
        // USB设备关闭连接
        @Override
        public void onDisconnect(UsbDevice device, USBMonitor.UsbControlBlock ctrlBlock) {
            if(!deviceIsUartVideoDevice(device)) {
                return;
            }

            if(!deviceHasConnected(device)) {
                return;
            }

            disconnected();
        }
        // USB device obtained permission failed
        // USB设备权限获取失败
        @Override
        public void onCancel() {

        }
    };


    private boolean deviceHasConnected(UsbDevice device) {
        return device != null && device.equals(uartDevice);
    }

    private static boolean deviceIsUartVideoDevice(UsbDevice device) {
        return device != null && (device.getVendorId() == 4292 && device.getProductId() == 60000);
    }

    private synchronized void disconnected() {
        video.stopPlayback();
        uartDevice = null;

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        video = new VideoClient(this);

        video.setClientListener(new VideoClient.ClientListener() {

            @Override
            public void onH264Received(byte[] h264) {

                if(passageway == 1){
                    count += h264.length;
                    print(h264);
                }

            }

            @Override
            public void onGPSReceived(byte[] bytes) {
                // GPS data callback
                if(passageway == 2){
                    count += bytes.length;
                    print(bytes);
                }
            }

            @Override
            public void onDataReceived(byte[] bytes) {
                // Transmission data callback
                if(passageway == 3){
                    count += bytes.length;
                    print(bytes);
                }
            }

            @Override
            public void onDebugReceived(byte[] bytes) {
                // Debug data callback
                if(passageway == 4){
                    count += bytes.length;
                    print(bytes);
                }
            }

            @Override
            public void onError(String error) {
                // Error data callback

            }
        });


        mUSBMonitor = new USBMonitor(this, mOnDeviceConnectListener);
        final List<DeviceFilter> filters = DeviceFilter.getDeviceFilters(this, R.xml.device_filter);
        mUSBMonitor.setDeviceFilter(filters);
        mUSBMonitor.register();

        tv_content = findViewById(R.id.tv_content);
        tv_count = findViewById(R.id.tv_count);
        scrollView = findViewById(R.id.scrollView);
        spinner = findViewById(R.id.spacer);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                switch (position){
                    case 0:
                        passageway = 1;
                        break;
                    case 1:
                        passageway = 2;
                        break;
                    case 2:
                        passageway = 3;
                        break;
                    case 3:
                        passageway = 4;
                        break;
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
        spinner.setSelection(0);

        radioGroup = findViewById(R.id.radioGroup);
        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId){
                    case R.id.rt_hex:
                        hex = true;
                        break;
                    case R.id.rt_text:
                        hex = false;
                        break;
                }
            }
        });

        et_send = findViewById(R.id.et_send);
        findViewById(R.id.btn_send).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                video.sendData(et_send.getText().toString().trim().getBytes());
            }
        });
        findViewById(R.id.btn_clean).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sb = new StringBuilder();
                tv_content.setText("");
            }
        });
        findViewById(R.id.btn_reset_count).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                count = 0;
                tv_count.setText("收到：" + count);
            }
        });
    }

    private int count = 0;

    private void print(final byte[] bytes){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if(sb.length() > 50 * 1024){
                    sb = new StringBuilder();
                }
                if(hex){
                    sb.append(bytesToHex(bytes));
                    tv_content.setText(sb.toString());
                }else {
                    sb.append(new String(bytes));
                    tv_content.setText(sb.toString());
                }
                scrollView.fullScroll(ScrollView.FOCUS_DOWN);//滚动到底部
                tv_count.setText("收到：" + count);
            }
        });


    }


    public  String bytesToHex(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for(int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if(hex.length() < 2){
                sb.append(0);
            }
            sb.append(hex);
        }
        return sb.toString().toUpperCase();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        disconnected();

        if (mUSBMonitor != null) {
            mUSBMonitor.unregister();
            mUSBMonitor.destroy();
            mUSBMonitor = null;
        }
    }
}
